<?php

namespace Beerus\Modules\DesignerAdv\Controllers;

use App\Pockets\GridDataModel as pGridDataModel;
use App\Http\Controllers\Controller;
use Doraemon\cache\Queue;
use Doraemon\model\KaManage\KaDesignerCombo;
use Doraemon\model\KaManage\KaDesignerMatter;
use Doraemon\model\KaManage\KaDesignerPerch;
use Doraemon\model\KaManage\KaPerchOpLog;
use Doraemon\model\KaManage\KaResourceDetail;
use Doraemon\model\KaManage\KaResourcePlace;
use Doraemon\model\KaManage\KaResourceSku;
use Doraemon\model\Member;
use Doraemon\service\KaManage\Combo;
use Doraemon\service\KaManage\PerchInfo;
use Doraemon\service\KaManage\ResourceSku;
use Doraemon\service\position\Position4Ka;
use Illuminate\Http\Request;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Tab;
use Illuminate\Support\MessageBag;
use Encore\Admin\Widgets\Form;

class KaAdvScheduleController extends Controller
{
    const PAGE_SIZE = 10;
	const PERCH_SELECTED = 1;

	const WEEK = ["日","一","二","三","四","五","六"];

	// 投放KA广告的城市
	const CITIES = [
		"上海","成都","北京","广州","苏州","深圳","重庆","武汉","南京","西安","天津","杭州","合肥",
	];
	// 占位数据
	const PERCH_STATUS = [
		KaDesignerPerch::STATUS_NORMAL => '已选',
		KaDesignerPerch::STATUS_DELETE => '取消'
	];

	public function __construct()
	{
		parent::__construct();
		Admin::script('$(".pjax-container").attr("id","pjax-container");');
	}

	public function index(Request $request, Content $content, $tab_id = 1)
	{
		$params = $request->all();

		$page_size = $request->input('per_page', self::PAGE_SIZE);
		$page = $request->input('page', 1);

		$condition = $this->condition($params, $tab_id);
		$condition['ORDER'] = ['perch_date' => 'ASC'];
//		$condition['LIMIT'] = [
//			($page - 1) * $page_size,
//			$page_size
//		];

		$tab = new Tab();
		foreach (KaDesignerPerch::RESOURCE_DETAIL_TITLE as $type => $title) {
			$tab->addLink($title, '/admin/DesignerAdv/schedule_list/'. $type, $tab_id == $type);
		}

		return $content
			->header('KA广告占位/排期')
			->description('支持查看所有KA广告的占位和排期')
			->breadcrumb(
				['text' => KaDesignerPerch::RESOURCE_DETAIL_TITLE[$tab_id], 'url' => '/admin/DesignerAdv/schedule_list/'. $tab_id]
			)
			->body($tab)
			->row(self::indexGrid($condition, $tab_id));
	}

	/**
	 * 表格展示部分
	 * @param $condition
	 * @param $tab_id
	 * @return Grid
	 */
	public function indexGrid($condition, $tab_id)
	{
		// 资源位信息
		$resource_info = KaResourceDetail::select('*', [
			'AND' => [
				'type' => $tab_id
			],
			'ORDER' => [
				'sort' => 'ASC'
			]
		]);
		$map_resource_detail = array_column($resource_info, 'name', 'id');

		$date = time();
		if (!empty($condition['perch_date'])) {
			$date = strtotime($condition['perch_date']);
		}

		$days = date("t", $date);

		unset($condition['date']);
		$lists = KaDesignerPerch::select('*', $condition);
		$lists = empty($lists) ? [] : $lists;

		$total = 0;
		$data = $group_city = [];
		if (!empty($lists)) {
			unset($condition['ORDER']);
			unset($condition['LIMIT']);
			$user_ids = array_column($lists, 'uid');
			$user_info = Member::getUsers($user_ids);

			$total = KaDesignerPerch::count($condition);

			foreach ($lists as $item) {
				$position = KaResourcePlace::get('position', [
					'id' => $item['resource_place_id']
				]);
				$location = str_replace(["第", "位"], ["", ""], $map_resource_detail[$item['resource_detail_id']]);
				$row = [
					'id' => $item['id'],
					'city' => $item['city'],
					'location' => $location,
					'position' => $position
				];
				
				for ($i = 1;$i <= $days; $i++) {
					if ($item['day'] == $i) {
						$row['day'. $i] = empty($user_info[$item['uid']]) ? '' : $user_info[$item['uid']]['nick'];
					} else {
						$row['day'. $i] = '';
					}
				}

				$data[] = $row;
			}
		}

		$grid_model = new pGridDataModel($data);

		return Admin::grid(
			$grid_model,
			function (Grid $grid) use ($grid_model, $days, $date, $tab_id) {
			    $grid->disablePagination();
				$grid->disableCreateButton();
				$grid->disableExport();
				$grid->disableRowSelector();

				$grid->filter(function (Grid\Filter $filter) use ($tab_id) {
					$filter->disableIdFilter();

					switch ($tab_id) {
						case KaDesignerPerch::DESIGNER_LIST:
						case KaDesignerPerch::ARTICLE_CASE:
						case KaDesignerPerch::SEARCH_RESULT:
						case KaDesignerPerch::START_SCREEN:
							$filter->column(1 / 3, function ($filter) {
								$filter->equal('city', '服务城市')->select(self::CITIES);
							});
							$filter->column(1 / 3, function ($filter) {
								$filter->date('perch_date', '占位日期')->default(date('Y-m-d'));
							});
							$filter->column(1 / 3, function ($filter) {
								$filter->equal('uid', '用户uid');
							});
							break;
						case KaDesignerPerch::WECHAT_HHZ:
						case KaDesignerPerch::WECHAT_AWARD:
						case KaDesignerPerch::WEIBO_HHZ:
						case KaDesignerPerch::WEIBO_AWARD:
							$filter->column(1 / 3, function ($filter) {
								$filter->date('perch_date', '占位日期')->default(date('Y-m-d'));
							});
							$filter->column(1 / 3, function ($filter) {
								$filter->equal('uid', '用户uid');
							});
							break;
					}

					$filter->expand();
				});

				$grid->column('city', '城市');
				$grid->column('location', '位置');
				$grid->column('position', '具体位置');
				$grid->fixColumns(3);

				for ($i = 1;$i <= $days;$i++) {
					$time = mktime(0, 0, 0, date("m", $date), $i, date("Y", $date));
					$week = self::WEEK[date('w', $time)];
					$day = 'day'.$i;
					$grid->column($day, $i."日（{$week}）")->width(100)->display(function () use ($day, $tab_id){
						if (!empty($this->{$day})) {
							$url = "/admin/DesignerAdv/schedule/edit/{$this->id}?tab_id=". $tab_id;
							return '<a href="'.$url.'"> ' . $this->{$day} . '</a>';
						}
					});
				}

				$grid->actions(function (Grid\Displayers\Actions $actions) {
					$actions->disableDelete();
				});
				$grid->disableActions();
			}
		);
	}

	private function condition($request, $tab_id)
	{
		$condition = [
			'type' => $tab_id,
			'data_status' => self::PERCH_SELECTED,
		];

		if (!empty($request['perch_date'])) {
		    $perchDate = explode('-', $request['perch_date']);
            $condition['year'] = $perchDate[0];
            $condition['month'] = ltrim($perchDate[1], '0');
		} else {
            $condition['year'] = date('Y');
            $condition['month'] = date('n');
        }

		if ($request['city'] != '') {
			$condition['city'] = self::CITIES[$request['city']];
		}

		if (!empty($request['uid'])) {
			$condition['uid'] = $request['uid'];
		}

		return $condition;
	}

	public function edit(Request $request, Content $content, $id = 0)
	{
		$request = $request->all();
		$tab_id = $request['tab_id'];

		$tab = new Tab();
		$tab->add('占位详情信息', self::editAction($request, $id));

		$button = '<div style="text-align: right"><a href="/admin/DesignerAdv/schedule/cancel/'.
			$id. '?tab_id='.$tab_id.' " class="btn btn-primary" onclick="return confirm(\'确认取消占位吗？\');">取消占位</a>
                   </div>';

		return $content->header('占位/排期信息')
			->breadcrumb([
				'text' => '占位/排期列表',
				'url' => route('schedule.list', [
					'tab_id' => $tab_id
				])
			], ['text' => '修改占位/排期信息'])
			->body($button)
			->row($tab);
	}

	public function editAction($request, $id = 0)
	{
		$data = KaDesignerPerch::get('*', ['id' => $id]);

		$position = KaResourcePlace::get('position', [
			'id' => $data['resource_place_id']
		]);
		$data['position'] = $position;
		$data['edit_time'] = date('Y-m-d H:i:s', $data['edit_time']);

		$data['nick'] = Member::getNickByUid($data['uid']);

		$form = new Form($data);
		$form->text('id', '占位id')->setWidth(4, 2)->required('不能为空')->readonly();
		$form->text('uid', '用户uid')->setWidth(4, 2)->required('不能为空')->readonly();
		$form->text('nick', '用户昵称')->setWidth(4, 2)->required('不能为空')->readonly();
		$form->text('city', '服务城市')->setWidth(4, 2)->required('不能为空')->readonly();

		$form->select('type', '展示位')->setWidth(4, 2)
			->options(KaDesignerPerch::RESOURCE_DETAIL_TITLE)
			->required('不能为空')->readOnly();
		if (in_array($data['type'], [KaDesignerPerch::DESIGNER_LIST, KaDesignerPerch::ARTICLE_CASE, KaDesignerPerch::SEARCH_RESULT])) {
			list($options, $resource_ids, $detail_ids) = self::getResource($data['type']);
			$form->select('resource_detail_id', '资源位详情')->options($options)
				->when($detail_ids[0], function ($form) use ($detail_ids) {
					$form->select('resource_place_id', '实际位置')->options(self::getPlace($detail_ids[0]))
						->setWidth(4, 2);
				})
				->when($detail_ids[1], function ($form) use ($detail_ids) {
					$form->select('resource_place_id', '实际位置')->options(self::getPlace($detail_ids[1]))
						->setWidth(4, 2);
				})
				->setWidth(4, 2);
		} else {
			$form->hidden('resource_detail_id', '资源位详情');
		}
		$form->date('perch_date', '占位日期')->setWidth(4, 2)->required('不能为空');
		$form->select('data_status', '占位状态')->default(KaDesignerPerch::STATUS_NORMAL)->readOnly()
			->setWidth(4, 2)->options(self::PERCH_STATUS)->required('不能为空');
		$form->text('edit_time', '修改时间')->setWidth(4, 2)->readonly();

		$form->disableReset();
		
		if ($data['data_status'] == KaDesignerPerch::STATUS_DELETE) {
			$form->disableSubmit();
		}
		
		$form->confirm('确定提交吗？');

		$form->action('/admin/DesignerAdv/schedule_list/save?tab_id='. $request['tab_id']);

		return $form->render();
	}

	public function save(Request $request)
	{
		$params = $request->all();
		$id = $params['id'];

		$date_array = explode('-', $params['perch_date']);
		$new_reserve_date = [
			'year' => (int)$date_array[0],
			'month' => (int)$date_array[1],
			'day' => (int)$date_array[2],
		];

		$perch_info = KaDesignerPerch::get('*', [
			'id' => $id
		]);

		// 检查选择的资源位详情和实际位置是否匹配
		if (in_array($params['type'], [
				KaDesignerPerch::DESIGNER_LIST,
				KaDesignerPerch::ARTICLE_CASE,
				KaDesignerPerch::SEARCH_RESULT]
			)) {
			if (!KaResourcePlace::count([
				'id' => $params['resource_place_id'],
				'resource_detail_id' => $params['resource_detail_id'],
			])) {
				$error = new MessageBag([
					'title' => '选择的资源位详情和实际位置不匹配'
				]);

				return back()->with(compact('error'));
			}
		} else {
		}

		if ($perch_info['resource_detail_id'] != $params['resource_detail_id']
			|| $perch_info['perch_date'] != $params['perch_date']) {
			// 检查资源位sku初始化数据
			$isHaveSku = ResourceSku::isHaveSku($params['resource_detail_id'], $params['city'], $params['perch_date']);
			if (!$isHaveSku) {
				$error = new MessageBag([
					'title' => '该资源位已被占满'
				]);

				return back()->with(compact('error'));
			}

			if ($isHaveSku == ResourceSku::NO_SKU_RECORD) {
				// 没有库存记录则尝试插入库存记录
				$detailInfo = KaResourceDetail::getDetailInfoById($params['resource_detail_id']);
				try {
					$data = [
						'city' => $params['city'],
						'resource_detail_id' => $params['resource_detail_id'],
						'sku_num' => $detailInfo['num'],
						'perch_date' => $params['perch_date']
					];

					if (!KaResourceSku::addSkuRecord($data)) {
						admin_error('错误提示', '库存记录初始化失败');
						return false;
					}
				} catch (\Exception $e) {
					// 发生插入异常则说明已经有人先初始化，则尝试正常占位流程
				}
			}
		}

		$res = KaDesignerPerch::action(function() use ($request, $params, $new_reserve_date, $perch_info) {
			$perch_id = (int)$params['id'];

			$old_data = [
				'perch_id' => $perch_id,
				'uid' => (int)$perch_info['uid'],
				'city' => $perch_info['city'],
				'year' => (int)$perch_info['year'],
				'month' => (int)$perch_info['month'],
				'day' => (int)$perch_info['day'],
				'type' => (int)$perch_info['type'],
				'resource_detail_id' => (int)$perch_info['resource_detail_id'],
				'resource_place_id' => (int)$perch_info['resource_place_id'],
				'perch_date' => $perch_info['perch_date'],
				'data_status' => $perch_info['data_status']
			];

			$new_data = [
				'perch_id' => $perch_id,
				'uid' => (int)$request['uid'],
				'city' => $params['city'],
				'year' => $new_reserve_date['year'],
				'month' => $new_reserve_date['month'],
				'day' => $new_reserve_date['day'],
				'type' => (int)$params['type'],
				'resource_detail_id' => (int)$params['resource_detail_id'],
				'resource_place_id' => (int)$params['resource_place_id'],
				'perch_date' => $params['perch_date'],
				'data_status' => (int)$params['data_status']
			];

			KaPerchOpLog::insert([
				'uid' => $params['uid'],
				'perch_id' => $perch_id,
				'old_data' => json_encode($old_data),
				'new_data' => json_encode($new_data),
				'op_type' => KaPerchOpLog::OP_SAVE,
				'edit_time' => date('Y-m-d H:i:s'),
				'admin_id' => Admin::user()->id
			]);

			$data_status = (int)$params['data_status'];

			// 区分修改数据取消占位的几种情况：
			// 资源位详情变化、实际位置变化、占位日期变化
			if ($perch_info['resource_detail_id'] != $params['resource_detail_id']
				|| $perch_info['perch_date'] != $params['perch_date']) {
				// 处理原占位库存
				$skuInfo = KaResourceSku::getSkuInfoByResourceIdAndCityDate($perch_info['resource_detail_id'], $perch_info['city'], $perch_info['perch_date']);
				KaResourceSku::reducePerchNum($skuInfo['id'], $skuInfo['perch_num']);
				/*处理新占位*/
				// 查询当前库存
				$skuInfo = KaResourceSku::getSkuInfoByResourceIdAndCityDate($params['resource_detail_id'], $params['city'], $params['perch_date']);
				if (KaResourceSku::addPerchNum($skuInfo['id'], $skuInfo['perch_num']) === false) {
					admin_error('错误提示', '预定占位失败');
					return false;
				}

				$data_status = KaDesignerPerch::STATUS_NORMAL;
			}

			$data = [
				'year' => $new_reserve_date['year'],
				'month' => $new_reserve_date['month'],
				'day' => $new_reserve_date['day'],
				'resource_detail_id' => (int)$params['resource_detail_id'],
				'resource_place_id' => (int)$params['resource_place_id'],
				'perch_date' => $params['perch_date'],
				'data_status' => $data_status,
				'edit_time' => time()
			];

			KaDesignerPerch::update($data, [
				'id' => $perch_id
			]);

			// 修改广告套餐剩余天数
            try {
                Combo::adminUpdateRemainDayWhenEdit($request['uid'], $old_data, $new_data);
            } catch (\Exception $e) {
                admin_error('错误提示', $e->getMessage());
                return false;
            }

			// 同步素材占位时间
			KaDesignerMatter::update([
				'perch_date' => $params['perch_date'],
				'resource_detail_id' => $params['resource_detail_id'],
				'edit_time' => time()
			], [
				'perch_id' => $perch_id
			]);

			// 搜索结果、整屋审核通过投队列
			if (in_array((int)$params['type'], [KaDesignerPerch::ARTICLE_CASE, KaDesignerPerch::SEARCH_RESULT])
				&& $params['data_status'] == KaDesignerPerch::STATUS_NORMAL) {
				$matter_info = KaDesignerMatter::get('*', [
					'data_status' => KaDesignerMatter::STATUS_APPROVE,
					'perch_id' => $perch_id
				]);

				if (!empty($matter_info)) {
					Queue::insertQueue('queue/Resource/Sync', [
						'perch_id' => $perch_id
					], Queue::QUEUE_DORAEMON);
				}
			}

			return true;
		});

		if ($res) {
			admin_success('提示', '保存成功');
		}
		return redirect("/admin/DesignerAdv/schedule/edit/$id?tab_id=". $request['tab_id']);
	}

	/**
	 * 获取展示位的资源详情
	 * @param $type
	 * @return array
	 */
	public function getResource($type)
	{
		$resource = KaResourceDetail::select('*', [
			'type' => $type
		]);

		$resource_ids = $options = $detail_ids = [];
		foreach ($resource as $item) {
			$options[$item['id']] = $item['name']. "（最多{$item['num']}个）";
			$resource_ids[] = $item['id'];
			$detail_ids[] = $item['id'];
		}

		return [$options, $resource_ids, $detail_ids];
	}

	public function getPlace($resource_detail_id)
	{
		$place = KaResourcePlace::select('*', [
			'resource_detail_id' => $resource_detail_id
		]);

		$options = [];
		foreach ($place as $item) {
			$options[$item['id']] = $item['position'];
		}

		return $options;
	}

	public function cancel($id, Request $request, $from = 1)
	{
		$perchInfo = KaDesignerPerch::get('*', [
			'id' => $id
		]);

		if ($from) {
			if ($perchInfo['data_status'] == KaDesignerPerch::STATUS_DELETE) {
				$error = new MessageBag([
					'title' => '占位已取消，重复取消无效'
				]);

				return back()->with(compact('error'));
			}
		}

		KaDesignerPerch::action(function() use ($perchInfo) {
			if (!KaDesignerPerch::cancelPerch($perchInfo['id'])) {
				$error = new MessageBag([
					'title' => '取消占位失败'
				]);

				return back()->with(compact('error'));
			}
			$skuInfo = KaResourceSku::getSkuInfoByResourceIdAndCityDate($perchInfo['resource_detail_id'], $perchInfo['city'], $perchInfo['perch_date']);
			// 更新库存
			if (!KaResourceSku::reducePerchNum($skuInfo['id'], $skuInfo['perch_num'])) {
				$error = new MessageBag([
					'title' => '取消占位未成功'
				]);

				return back()->with(compact('error'));
			}
			// 更新套餐剩余数量，取消占位操作是该资源位剩余天数+1
            $effectKaOrder = Combo::getPerchDateMatchKaOrder($perchInfo['uid'], $perchInfo['perch_date']);
            $comboInfo = KaDesignerCombo::getResourceDetailComboInfo($perchInfo['uid'], $perchInfo['type'], $perchInfo['resource_detail_id'], $effectKaOrder['ka_order_id']);
			if (empty($comboInfo)) {
                $error = new MessageBag([
                    'title' => '该KA设计师未初始化广告套餐信息，请至KA订单处确认！'
                ]);
                return back()->with(compact('error'));
            }
			if (!KaDesignerCombo::updateRemainComboDay($perchInfo['uid'], $perchInfo['type'], $perchInfo['resource_detail_id'], intval($comboInfo['remain_combo_day'])+1, $effectKaOrder['ka_order_id'])) {
                $error = new MessageBag([
                    'title' => '更新广告剩余套餐天数失败！'
                ]);
                return back()->with(compact('error'));
            }

			// 删除对应占位的素材
			KaDesignerMatter::update([
				'data_status' => KaDesignerMatter::STATUS_DELETE
			], [
				'perch_id' => $perchInfo['id']
			]);

			$old_data = [
				'perch_id' => (int)$perchInfo['id'],
				'city' => $perchInfo['city'],
				'year' => (int)$perchInfo['year'],
				'month' => (int)$perchInfo['month'],
				'day' => (int)$perchInfo['day'],
				'type' => (int)$perchInfo['type'],
				'resource_detail_id' => (int)$perchInfo['resource_detail_id'],
				'resource_place_id' => (int)$perchInfo['resource_place_id'],
				'perch_date' => $perchInfo['perch_date'],
				'data_status' => (int)$perchInfo['data_status']
			];

			$new_data = $old_data;
			$new_data['data_status'] = KaDesignerPerch::STATUS_DELETE;

			KaPerchOpLog::insert([
				'uid' => $perchInfo['uid'],
				'perch_id' => $perchInfo['id'],
				'old_data' => json_encode($old_data),
				'new_data' => json_encode($new_data),
				'op_type' => KaPerchOpLog::OP_CANCEL,
				'edit_time' => date('Y-m-d H:i:s'),
				'admin_id' => Admin::user()->id
			]);
		});

		$success = new MessageBag([
			'title' => '取消占位成功'
		]);

		return redirect("/admin/DesignerAdv/schedule/edit/$id?tab_id=". $request['tab_id'])->with(compact('success'));
	}
}
